/**
 * 以后这些函数库全部都需要载入
 * 加油吧小伙伴们 by Mike/大当家
 */

let core = require("core.js");

//方便其他文件自动提示，本质上在这儿没有作用
let __DIR__;
let thisObject;

/**
 * 默认存redis
 * @param ob
 */
function saveObject(ob) {
   return core.saveObject(ob);
}

function restoreObject(ob) {
    return core.restoreObject(ob);
}

function environment() {
    return core.environment(arguments);
}


function verifyInherits(file,pob) {
    return core.verifyInherits(file,pob);
}


/**
 * 获取对象的内容物
 * 如果这个对象身上还挂着内容的文件地址，就重新加载
 * @param ob
 */
function allInventory(ob) {
    return core.allInventory(ob);
}


function present() {
    return core.present(arguments);
}


function jsonp(obj) {
    return core.jsonp(obj);
}


function arrayp(ob) {
    return core.arrayp(ob);
}

function moveObject(source, dest) {
    return core.moveObject(source, dest);
}


function newObj() {
    return core.newObj(arguments);
}


/**
 *
 *
 *  根据文件名
 *  寻找内存中的对象，没有就新建一个对象返回
 *  该方法永远会返回一个对象，除非传入的文件不存在
 *  所以她可以作为findObject使用
 *  假定 传入的参数
 *  x/user.js
 *  x/user.js#123
 *
 *    type等于2时，传入的一定是   x/user.js#123

 所以 是两种查找方式 一种是模糊查找 一种是精准查找
 模糊查找
 loadObject("adm/daemons/master.js");
 精准查找
 loadObject("clone/user.js#123",1);
 *
 *
 *  @author Mike/Fang.j/大当家
 *
 */
function loadObject() {

    return core.loadObject(arguments);
}


// function tellObject(ob, msg) {
//     os.tellObject(ob, msg + "\n");
// }


function tellObject(ob, msg) {

    let Warp = function (ob, msg) {
        this.msg = msg;
        this.ob = ob;
        this.to = function () {
            this.msg += "\n";
            if (this.ob.get("obType") == "isPlayer") {
                this.ob.get("agent").getSession().sendText(this.msg);
            } else if (this.ob.get("obType") == "isAgent") {
                //直接就是session对象;
                this.ob.getSession().sendText(this.msg);
            }
        }
    }
    let warp = new Warp(ob, msg);

    // msg += "\n";
    // if (ob.get("obType") == "isPlayer") {
    //     ob.get("agent").getSession().sendText(msg);
    // } else if (ob.get("obType") == "isAgent") {
    //     //直接就是session对象;
    //     ob.getSession().sendText(msg);
    // }
    return warp;


}



function destruct(ob) {
    return core.destruct(ob);
}

function findPlayer(arg) {
    return core.findPlayer(arg);
}

function userp(ob) {
    return core.userp(ob);
}

function getObjects() {
    return core.getObjects();
}

/**
 * 约定只有对象和Json对象才是object
 * string false undefined int number doubel 都不是....
 * @param ob
 * @returns {*}
 * @author mike/Fang.j/大当家
 */
function objectp(ob) {
    return core.objectp(ob);
}

function functionp(ob) {
    return core.functionp(ob);
}


function stringp(ob) {
    return core.stringp(ob);
}

//获取所有的玩家，包括连接已经断开的玩家

function getUsers() {
    return core.getUsers();
}

function getUser(account) {

    return core.getUser(account);
}


function findObject(file) {
    return core.findObject(file);
}


function findObject(file) {
    return core.findObject(file);
}



/**
 *
 * 一个参数时，按照 <文件名> 查找
 * 2个参数时，按照  <文件名#123> 查找
 *
 * @returns {boolean|*}
 * @constructor
 */
// function D() {
//
//     let arg = arguments;
//
//     if (arg.length > 0 && !stringp(arg[0])) {
//         os.debug("the first argument must be a string");
//         return;
//     }
//
//
//     if (arg.length == 1) {
//         return os.D(arg[0]);
//     } else if (arg.length == 2) {
//         //找不到就创建新的...
//         return os.D(arg[0], arg[1]);
//     }
//     return false;
//
// }

/**
 *
 * @param u user
 * @param a agent
 */
function confix(u, a) {
    core.confix(u, a);
}

//占时不处理
function notifyFail(str) {

}

/**
 * 根据网络连接查找玩家
 * @param sessionId
 * @returns {*|boolean}
 */
function findUserByAgent(sessionId) {
    return core.findUserByAgent(sessionId);
}

function undefinedp(ob) {
    return core.undefinedp(ob);
}


function baseFileName(ob) {
    return ob.__baseFileName__;
}


function fileNameSid() {
    let arg = arguments;
    if (arg.length <= 0) {
        return thisObject.__fileName__;
    } else if (arg.length == 1) {
        return arg[0].__fileName__;
    }
}

function subList(f) {
    return core.subList(f);
}



function inputTo(agentObj,func,args) {

    //args[0] obj  args[1] msg
    agentObj["inputFunc"] = func;
    agentObj["inputFuncArgs"] = args;


}

function $$(ob) {
    return ob.__parentData__.func;
}


function command(ob,msg, t) {
    //按照现代通信协议，指令不应该重名 就是算有权限，也可以在同个指令下做判断....
    // let commands = {
    //     look: "cmds/std/look.js",
    //     obs: "cmds/adm/obs.js",
    //     go: "cmds/std/go.js",
    //     kill: "cmds/std/kill.js",
    //     update: "cmds/adm/update.js",
    //     save: "cmds/std/save.js",
    //     sim: "cmds/sim/sim.js",
    // }

    let gt = os.getGlobalThis();
    let commands = gt["gameCmds"];

    os.debug(msg, "消息内容")
    //查找第一个空格 进行分割 。。。 因为存在这样的问题 cmd 1 2 3 4 5 6
    let str = msg.split(" ");
    let arg, cmd;
    // os.debug(JSON.stringify(str), "转换后的消息内容")

    cmd = str[0];
    if (str.length < 2) {
        arg = [];
    } else {
        arg = str.splice(1, str.length-1);
    }

    // os.debug( JSON.stringify(arg),"参数数组情况" );

    arg = arg.length <= 0 ? "" : arg.join(" ");

    if (cmd in commands) {
        loadObject(commands[cmd]).main(ob, arg);
    } else {
        //全局指令没有，就在玩家所在的环境中找指令
        let cmds = {}, env = environment(ob);
        if (!objectp(env) || undefinedp(cmds = env.get("cmds")) || undefinedp(cmds[cmd])) {
            tellObject(thisObject, "你当前所在的环境和系统都没有这个指令...").to();
            os.debug("你当前所在的环境和系统都没有这个指令...");
            return;
        }

        cmds[cmd](thisObject, arg);

    }

}




//-----------------------------------------------------------------------------
/**
 * 在一个区间生成随机数
 * @param min
 * @param max
 * @returns {number}
 */
function rangeRondom(min, max) {
    return Math.floor(Math.random() * (max - min + 1) + min);
}

/**
 * 根据min和max生成随机数
 * @returns {number}
 */
function random() {
    let min, max, arr = arguments;
    if (arr.length == 2) {
        min = arr[0];
        max = arr[1];
        return Math.floor(Math.random() * (max - min + 1) + min);
    }
}


/**
 * 深拷贝
 * @param obj
 * @returns {*[]}
 */
function deepClone(obj) {
    let objClone = Array.isArray(obj) ? [] : {};
    if (obj && typeof obj === "object" && obj.hasOwnProperty) {
        for (key in obj) {
            if (obj.hasOwnProperty(key)) {
                //判断ojb子元素是否为对象，如果是，递归复制
                if (obj[key] && typeof obj[key] === "object") {
                    objClone[key] = deepClone(obj[key]);
                } else {
                    //如果不是，简单复制
                    objClone[key] = obj[key];
                }
            }
        }
    }
    return objClone;
}


/**
 * 随机从一个数组里面抽取一个元素
 * @param arr
 * @returns {*}
 */
function getRandomOneOfArr(arr) {
    return arr[Math.floor(Math.random() * arr.length)];
}


/**
 * 数字货币转换
 * @param value
 * @returns {string}
 */
function transformNumToCh(value) {
    let newValue = ['', '', ''];
    let fr = 1000;
    const ad = 1;
    let num = 3;
    let fm = 1;
    while (value / fr >= 1) {
        fr *= 10;
        num += 1;
        console.log('数字', value / fr, 'num:', num);
    }
    if (num <= 4) { // 千
        newValue[1] = '千';
        newValue[0] = parseInt(value / 1000) + '';
    } else if (num <= 8) { // 万
        let text1 = parseInt(num - 4) / 3 > 1 ? '千万' : '万';
        // tslint:disable-next-line:no-shadowed-variable
        fm = '万' === text1 ? 10000 : 10000000;
        newValue[1] = text1;
        newValue[0] = (value / fm) + '';
    } else if (num <= 16) {// 亿
        let text1 = (num - 8) / 3 > 1 ? '千亿' : '亿';
        text1 = (num - 8) / 4 > 1 ? '万亿' : text1;
        text1 = (num - 8) / 7 > 1 ? '千万亿' : text1;
        // tslint:disable-next-line:no-shadowed-variable
        let fm = 1;
        if ('亿' === text1) {
            fm = 100000000;
        } else if ('千亿' === text1) {
            fm = 100000000000;
        } else if ('万亿' === text1) {
            fm = 1000000000000;
        } else if ('千万亿' === text1) {
            fm = 1000000000000000;
        }
        newValue[1] = text1;
        newValue[0] = parseInt(value / fm) + '';
    }
    if (value < 1000) {
        newValue[1] = '';
        newValue[0] = value + '';
    }
    return newValue.join('');
}

/**
 * 后面优化
 * @returns {*}
 */
function sprintf() {
    var s = arguments[0];
    for (var i = 0; i < arguments.length - 1; i++) {
        var reg = new RegExp("\\{" + i + "\\}", "gm");
        s = s.replace(reg, arguments[i + 1]);
    }
    return s;
}

function uint8ArrayToString(fileData) {

    return utf8ArrayToStr(fileData);

}


/* utf.js - UTF-8 <=> UTF-16 convertion
*
* Copyright (C) 1999 Masanao Izumo <iz@onicos.co.jp>
* Version: 1.0
* LastModified: Dec 25 1999
* This library is free.  You can redistribute it and/or modify it.
* 1999年 日本人就再玩这些了，国人加油！
*
*/

function utf8ArrayToStr(array) {
    var out, i, len, c;
    var char2, char3;

    out = "";
    len = array.length;
    i = 0;
    while (i < len) {
        c = array[i++];
        switch (c >> 4) {
            case 0:
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
            case 6:
            case 7:
                // 0xxxxxxx
                out += String.fromCharCode(c);
                break;
            case 12:
            case 13:
                // 110x xxxx   10xx xxxx
                char2 = array[i++];
                out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
                break;
            case 14:
                // 1110 xxxx  10xx xxxx  10xx xxxx
                char2 = array[i++];
                char3 = array[i++];
                out += String.fromCharCode(((c & 0x0F) << 12) |
                    ((char2 & 0x3F) << 6) |
                    ((char3 & 0x3F) << 0));
                break;
        }
    }

    return out;
}


// String.prototype.to = function () {
//     let arguments;
//     let str = this.toString();
//     if (arguments.length <= 0) {
//         //如果任何时候都需要使用JSON修改这儿
//         return str;
//     } else if (arguments.length > 0) {
//         return {protype: arguments[0], msg: str, data: arguments[1]};
//     }
// };

//计算时间间隔，也就是时间段。例:03:34:45
function formatTimeDuring (mss) {
    var hours = parseInt(mss / (1000 * 60 * 60));
    var minutes = parseInt((mss % (1000 * 60 * 60)) / (1000 * 60));
    var seconds = parseInt((mss % (1000 * 60)) / 1000);
    var str =
        pad(hours)+
        ":" +
        pad(minutes) +
        ":" +
        pad(seconds);
    return str;
}


/**
 * 传入
 * @param mss
 * @param t
 * @returns {number}
 */
function timeDuring (mss,t) {
    var hours = parseInt(mss / (1000 * 60 * 60));
    var minutes = parseInt((mss % (1000 * 60 * 60)) / (1000 * 60));
    var seconds = parseInt((mss % (1000 * 60)) / 1000);
    let ret;
    switch (t) {
        case "s":
            ret =  seconds;break;
        case "m":
            rret = minutes;break;
        case "h":
            ret = hours;break;
        default:
            ret = seconds;
    }
    return  ret;
}




function trace (count) {
    var caller = arguments.callee.caller;
    var i = 0;
    count = count || 10;
    os.debug("***----------------------------------------  ** " + (i + 1));

    os.debug(JSON.stringify(arguments));

    while (caller && i < count) {
        os.debug(caller.toString());
        caller = caller.caller;
        i++;
        os.debug("***---------------------------------------- ** " + (i + 1));
    }
}



/**
 * 时间格式化
 * fmt = "yyyy-MM-dd hh:mm:ss"
 * @param {*} date Date对象 或 时间戳
 * @param {*} fmt "yyyy-MM-dd hh:mm:ss"
 */
 function formatTime (date, fmt) {
    if (!date) return date;
    if (!(date instanceof Date)) {
        date = new Date(date);
    }
    var o = {
        "M+": date.getMonth() + 1, //月份
        "d+": date.getDate(), //日
        "h+": date.getHours(), //小时
        "m+": date.getMinutes(), //分
        "s+": date.getSeconds(), //秒
        "q+": Math.floor((date.getMonth() + 3) / 3) //季度
    };
    // 格式化年
    if (/(y+)/.test(fmt)) {
        fmt = fmt.replace(
            RegExp.$1,
            (date.getFullYear() + "").substr(4 - RegExp.$1.length)
        );
    }
    // 格式化毫秒
    if (/(S+)/.test(fmt)) {
        const tmp = date.getMilliseconds();
        fmt = fmt.replace(
            RegExp.$1,
            ("000" + tmp).substr(("" + tmp).length)
        );
    }
    // 格式化其它
    for (var k in o) {
        if (new RegExp("(" + k + ")").test(fmt)) {
            fmt = fmt.replace(
                RegExp.$1,
                RegExp.$1.length === 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length)
            );
        }
    }
    return fmt;
}

/**
 * 通过最近时间和单位（最近一周，最近一月等），获取时间段（时间戳数组）
 * @param {*} timeValue 最近时间
 * @param {*} timeUnit  时间单位
 */
 function getTimeRangeByUnit (timeValue, timeUnit) {
    let rangeArr = [];
    const start = new Date().getTime();
    const end = new Date().getTime();

    switch (timeUnit) {
        case "hours":
            rangeArr = [start - 3600 * 1000 * timeValue, end];
            break;
        case "day":
            rangeArr = [
                start - 3600 * 1000 * 24 * timeValue,
                end
            ];
            break;
        case "week":
            rangeArr = [
                start - 3600 * 1000 * 24 * 7 * timeValue,
                end
            ];
            break;
        case "month":
            rangeArr = [
                start - 3600 * 1000 * 24 * 30 * timeValue,
                end
            ];
            break;
        case "year":
            rangeArr = [
                start - 3600 * 1000 * 24 * 365 * timeValue,
                end
            ];
            break;
    }
    return rangeArr;
}
function writeLog(logFileName, content) {
    //os.debug("这是readLogFile方法！");
    os.fs.readFileSync(os.fs.path.processRootPath+"/"+logFileName, function (err, data) {
        if (err.toString()!="") {
            os.debug(err.toString());
            return;
        }
        let readContent = uint8ArrayToString(data);
        //os.debug("log文件的内容为:"+readContent);
        writeLogFile(logFileName,readContent, content);
        return;
    });
}
function writeLogFile(logFileName,readContent,content){
    let time = getTime();
    let data = content + " *** " + time + " ***\r\n" + readContent;
    //let data = content + " *** " + time + " ***\r\n";
    os.fs.writeFileSync(logFileName, data, {
    //append:true,
    err: function (errmsg) {
        os.debug(errmsg);
        //return false;
    },
    ok:function(){
        os.debug(content+"写log文件成功");
    }
});
//return true;
}
function getTime() {
    let formatDateTime = function (date) {
        var y = date.getFullYear();
        var m = date.getMonth() + 1;//注意这个“+1”
        m = m < 10 ? ('0' + m) : m;
        var d = date.getDate();
        d = d < 10 ? ('0' + d) : d;
        var h = date.getHours();
        h = h < 10 ? ('0' + h) : h;
        var minute = date.getMinutes();
        minute = minute < 10 ? ('0' + minute) : minute;
        var second = date.getSeconds();
        second = second < 10 ? ('0' + second) : second;
        return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second;
    };
    time = new Date() //Mon Aug 31 2020 15:43:25 GMT+0800 (中国标准时间)
    //timeStamp = time.getTime() 
    timeString = formatDateTime(time)
    //console.log('timeString:', timeString) // 2020-03-01 00:00:00
    return timeString;
}

module.exports  = {
    writeLog,
    newObj,
    loadObject,
    objectp,
    uint8ArrayToString,
    undefinedp,
    stringp,
    getObjects,
    getRandomOneOfArr,
    getUser,
    getUsers,
    findUserByAgent,
    fileNameSid,
    trace,
    destruct,
    saveObject,
    timeDuring,
    restoreObject,
    inputTo,
    findPlayer,
    $$,
    command,

}





